package com.cj.core.crypto;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.*;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.cj.core.response.CJExceptionHandle;
import com.cj.core.response.REnum;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * @Description: AES加密/解密工具类
 * @Author: 陈军
 * @Tel: 13984919416
 * @Date: 2022/5/14
 */
public class AESUtil {
    // 加密key
    private static final String PUBLIC_KEY_16 = "CJ19941qaz2wsx99";
    private static final String PUBLIC_KEY_24 = "CJ19941qaz2wsx9920200520";
    private static final String PUBLIC_KEY_32 = "CJ19941qaz2wsx9920200520abcdefgh";
    // 加盐
    private static final String IV = "chenjun20200520@";

    // AES+EBC模式==========================================》》》
    // EBC加密+自带密钥加密
    public static String encEBC(String key, String content) throws Exception {
        return Base64.getEncoder().encodeToString(SecureUtil.aes(key.getBytes()).encrypt(content));
    }

    // 加密128位
    public static String encEBC16(String content) throws Exception {
        return encEBC(PUBLIC_KEY_16, content);
    }

    // 加密192位
    public static String encEBC24(String content) throws Exception {
        return encEBC(PUBLIC_KEY_24, content);
    }

    // 加密256位
    public static String encEBC32(String content) throws Exception {
        return encEBC(PUBLIC_KEY_32, content);
    }

    // EBC解密+自带密钥加密
    public static String dncEBC(String key, String content) throws Exception {
        return Base64.getEncoder().encodeToString(SecureUtil.aes(key.getBytes()).decrypt(content));
    }

    // 解密128位
    public static String dncEBC16(String content) throws Exception {
        return dncEBC(PUBLIC_KEY_16, content);
    }

    // 解密192位
    public static String dncEBC24(String content) throws Exception {
        return dncEBC(PUBLIC_KEY_24, content);
    }

    // 解密256位
    public static String dncEBC32(String content) throws Exception {
        return dncEBC(PUBLIC_KEY_32, content);
    }

    // AES+CBC模式==========================================》》》
    // CBC加密模式
    public static String encCBC(String key, String iv, String content) throws Exception {
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv.getBytes());
        return Base64.getEncoder().encodeToString(aes.encrypt(content));
    }

    // CBC加密128位
    public static String encCBC16(String content) throws Exception {
        return encCBC(PUBLIC_KEY_16, IV, content);
    }

    // CBC加密192位
    public static String encCBC24(String content) throws Exception {
        return encCBC(PUBLIC_KEY_24, IV, content);
    }

    // CBC加密256位
    public static String encCBC32(String content) throws Exception {
        return encCBC(PUBLIC_KEY_32, IV, content);
    }

    // CBC解密模式
    public static String dncCBC(String key, String iv, String content) throws Exception {
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv.getBytes());
        return new String(aes.decrypt(content));
    }

    // CBC解密128位
    public static String dncCBC16(String content) throws Exception {
        return dncCBC(PUBLIC_KEY_16, IV, content);
    }

    // CBC解密192位
    public static String dncCBC24(String content) throws Exception {
        return dncCBC(PUBLIC_KEY_24, IV, content);
    }

    // CBC解密256位
    public static String dncCBC32(String content) throws Exception {
        return dncCBC(PUBLIC_KEY_32, IV, content);
    }


    public static void main(String[] args) throws Exception {
        String content = "Hello, AES!";
        System.out.println("原文：" + content);
        System.out.println("EBC加密128位：" + AESUtil.encEBC16(content));
        System.out.println("EBC解密128位：" + AESUtil.dncEBC16(AESUtil.encEBC16(content)));
        System.out.println("EBC加密192位：" + AESUtil.encEBC24(content));
        System.out.println("EBC解密192位：" + AESUtil.dncEBC24(AESUtil.encEBC24(content)));
        System.out.println("EBC加密256位：" + AESUtil.encEBC32(content));
        System.out.println("EBC解密256位：" + AESUtil.dncEBC32(AESUtil.encEBC32(content)));
        System.out.println("CBC加密128位：" + AESUtil.encCBC16(content));
        System.out.println("CBC解密128位：" + AESUtil.dncCBC16(AESUtil.encCBC16(content)));
        System.out.println("CBC加密192位：" + AESUtil.encCBC24(content));
        System.out.println("CBC解密192位：" + AESUtil.dncCBC24(AESUtil.encCBC24(content)));
        System.out.println("CBC加密256位：" + AESUtil.encCBC32(content));
        System.out.println("CBC解密256位：" + AESUtil.dncCBC32(AESUtil.encCBC32(content)));
    }

}